package org.feng.datasource.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.feng.datasource.DynamicDataSourceContextHolder;
import org.feng.datasource.ExchangeDataSource;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 切面实现动态数据源切换
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年05月05日 16时35分
 */
@Aspect
@Order(1)
@Component
public class DynamicDataSourceAspect {

    @Before("execution(public * org.feng.service.*.*(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("开始切入切换数据源...");
        ExchangeDataSource exchangeDataSource = parseMethodWithExchangeDataSource(joinPoint);
        if (Objects.isNull(exchangeDataSource)) {
            return;
        }
        String merchantKey = exchangeDataSource.value();
        System.out.println("merchantKey = " + merchantKey);
        DynamicDataSourceContextHolder.setDataSourceKey(merchantKey);
    }

    @After("execution(public * org.feng.service.*.*(..))")
    public void after() {
        System.out.println("切入数据源之后...");
        DynamicDataSourceContextHolder.removeDataSourceKey();
    }

    private ExchangeDataSource parseMethodWithExchangeDataSource(JoinPoint joinPoint) {
        Class<?> targetClass = joinPoint.getTarget().getClass();
        // 如果类上有切换数据源的注解
        if (targetClass.isAnnotationPresent(ExchangeDataSource.class)) {
            return targetClass.getAnnotation(ExchangeDataSource.class);
        }

        // 获取方法上的注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if (method.isAnnotationPresent(ExchangeDataSource.class)) {
            return method.getAnnotation(ExchangeDataSource.class);
        }
        return null;
    }
}
